package com.plm.mqshequ.config;

import com.plm.mqshequ.entity.Role;
import com.plm.mqshequ.entity.User;
import com.plm.mqshequ.service.RoleService;
import com.plm.mqshequ.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashSet;
import java.util.Set;

/**
 * @author Limi
 * @create 2019-01-17 18:39
 */
@Slf4j
public class ShiroRealm extends AuthorizingRealm {

    @Autowired
    private UserService userService;
    @Autowired
    private RoleService roleService;

    /**
     * 授权/权限验证
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        log.info("---------------------------->授权认证：");
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        // 查询用户角色
        User user = (User) principalCollection.getPrimaryPrincipal();
        String userId = user.getId();
        Role role = roleService.queryByUId(userId);
        // 将角色存到Set中，过滤重复角色
        Set<String> roleSet = new HashSet<>();
        roleSet.add(role.getRole());

        // 将角色名称组成的Set提供给授权info
        authorizationInfo.setRoles(roleSet);

        log.info("授权信息：authorizationInfo is {}", authorizationInfo);

        return authorizationInfo;
    }

    /**
     * 身份认证/登录
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken)
            throws AuthenticationException {
        log.info("---------------------------->登陆验证:");
        // 获取界面中输入的用户名和密码
        String email = (String) authenticationToken.getPrincipal();
        String password = new String((char[])authenticationToken.getCredentials());
        log.info("认证登录信息：username is {}, password id {}", email, password);

        // 通过用户名获取用户信息
        User user = userService.findByEmail(email);

        if (user == null) {
            throw new UnknownAccountException("用户名或密码错误");
        }

        // 此处是获取数据库内的账号、密码、盐值，保存到登陆信息info中
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
                user,
                user.getPassword(),
                ByteSource.Util.bytes(user.getEmail()),
                getName());

        log.info("认证登录的用户信息：user is {}", user);

        return authenticationInfo;
    }
}
